package com.jindy.module.transfer.service.impl;

import com.jindy.common.constant.Constants;
import com.jindy.common.core.domain.AjaxResult;
import com.jindy.common.core.domain.model.LoginUser;
import com.jindy.common.exception.base.BaseException;
import com.jindy.common.utils.DateUtils;
import com.jindy.common.utils.SecurityUtils;
import com.jindy.common.utils.StringUtils;
import com.jindy.module.approvalConfig.domain.ApprovalConfig;
import com.jindy.module.approvalConfig.mapper.ApprovalConfigMapper;
import com.jindy.module.approvalRecord.domain.ApprovalRecord;
import com.jindy.module.approvalRecord.mapper.ApprovalRecordMapper;
import com.jindy.module.stock.domain.Stock;
import com.jindy.module.stock.mapper.StockMapper;
import com.jindy.module.transfer.domain.SyTransferT;
import com.jindy.module.transfer.domain.TransferApprovedResult;
import com.jindy.module.transfer.mapper.SyTransferTMapper;
import com.jindy.module.transfer.service.ISyTransferTService;
import com.jindy.module.transferProduct.domain.SyTransferProductT;
import com.jindy.module.transferProduct.mapper.SyTransferProductTMapper;
import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 库存调拨Service业务层处理
 * 
 * @author jindy
 * @date 2023-04-12
 */
@Service
public class SyTransferTServiceImpl implements ISyTransferTService 
{
    @Resource
    private SyTransferTMapper syTransferTMapper;

    /**
     * 库存Mapper
     */
    @Resource
    private StockMapper stockMapper;

    /**
     * 调拨产品 mapper
     */
    @Resource
    private SyTransferProductTMapper syTransferProductTMapper;

    /**
     * 审批记录Mapper
     */
    @Resource
    private ApprovalRecordMapper approvalRecordMapper;

    /**
     * 配置表
     */
    @Resource
    private ApprovalConfigMapper approvalConfigMapper;

    /**
     * 查询库存调拨
     * 
     * @param id 库存调拨主键
     * @return 库存调拨
     */
    @Override
    public SyTransferT selectSyTransferTById(Long id)
    {
        SyTransferT syTransferT = syTransferTMapper.selectSyTransferTById(id);
        syTransferT.setSyTransferProductTList(syTransferProductTMapper.selectSyTransferProductListByTransferNo(syTransferT.getSerialNum()));
        return syTransferT;
    }

    /**
     * 查询库存调拨列表
     * 
     * @param syTransferT 库存调拨
     * @return 库存调拨
     */
    @Override
    public List<TransferApprovedResult> selectSyTransferTList(SyTransferT syTransferT)
    {
        List<TransferApprovedResult> syTransferApprovedList = syTransferTMapper.selectSyTransferApprovedList(syTransferT);
        for (TransferApprovedResult transferProductResult : syTransferApprovedList) {
            List<SyTransferProductT> syTransferProductTS = syTransferProductTMapper.selectSyTransferProductListByTransferNo(transferProductResult.getSerialNum());
            if (!CollectionUtils.isEmpty(syTransferProductTS)){
                transferProductResult.setSyTransferProductTList(syTransferProductTS);
            }
        }
        return syTransferApprovedList;
    }

    /**
     * 新增库存调拨
     * 
     * @param syTransferT 库存调拨
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertSyTransferT(SyTransferT syTransferT)
    {
        //判断是否登录
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (Objects.isNull(loginUser)){
            return AjaxResult.error(HttpStatus.SC_FORBIDDEN,"请先登录");
        }
        //校验必填及数量
        if(CollectionUtils.isEmpty(syTransferT.getSyTransferProductTList())){
            return AjaxResult.error(HttpStatus.SC_INTERNAL_SERVER_ERROR,"请选择调拨产品");
        }
        //判断是否重提交
        if (null==syTransferT.getId()){
            //新增调拨单
            addSyTransfer(syTransferT, loginUser);
        }else{
            //重提交
            syTransferT.setUpdateTime(DateUtils.parseDate(DateUtils.getTime()));
            syTransferT.setUpdateBy(loginUser.getUsername());
            updateSyTransferT(syTransferT);
            //删除审批记录
            approvalRecordMapper.deleteApprovalRecordBySerialNum(syTransferT.getSerialNum());
        }
        //增加审批
        addApprovalRecord(syTransferT,loginUser);
        return AjaxResult.success();
    }

    /**
     * 发起人是内部人员 流程记录
     *
     * @param syTransferT
     */
    @Transactional(rollbackFor = Exception.class)
    public void addApprovalRecord(SyTransferT syTransferT, LoginUser loginUser) {

        int sequence = 1;
        //  发起人
        ApprovalRecord firstApprovalRecord = getApprovalRecord(syTransferT, loginUser);
        firstApprovalRecord.setSequence(sequence);
        firstApprovalRecord.setApprovalStatus(Constants.COMPLETED);
        firstApprovalRecord.setTypeOperation(Constants.AGREE);
        firstApprovalRecord.setBusinessStatus(Constants.APPROVE);
        firstApprovalRecord.setApproverId(loginUser.getUserId());
        firstApprovalRecord.setApproverName(loginUser.getUsername());
        approvalRecordMapper.insertApprovalRecord(firstApprovalRecord);

        sequence++;
        //  第二审批人：物流人员，王秋月
        List<ApprovalConfig> approvalConfigList = approvalConfigMapper.selectApprovalConfigList(new ApprovalConfig("KCDB_WL", "1"));
        if (CollectionUtils.isEmpty(approvalConfigList)) {
            throw new RuntimeException("请检查审批配置信息：KCDB_WL");
        }
        addApprovalConfig(sequence, approvalConfigList,syTransferT, loginUser);

        sequence++;
        //  第三审批人：调出仓库负责人
        ApprovalRecord outApprovalRecord = getApprovalRecord(syTransferT, loginUser);
        outApprovalRecord.setSequence(sequence);
        outApprovalRecord.setApprovalStatus(Constants.NOT_APPROVED);
        outApprovalRecord.setApproverId(syTransferT.getOutRepertoryId());
        outApprovalRecord.setApproverName(syTransferT.getOutRepertoryName());
        approvalRecordMapper.insertApprovalRecord(outApprovalRecord);

        sequence++;
        //  第四审批人:调入仓库负责人
        ApprovalRecord inApprovalRecord = getApprovalRecord(syTransferT, loginUser);
        inApprovalRecord.setSequence(sequence);
        inApprovalRecord.setApprovalStatus(Constants.NOT_APPROVED);
        inApprovalRecord.setApproverId(syTransferT.getInRepertoryId());
        inApprovalRecord.setApproverName(syTransferT.getInRepertoryName());
        approvalRecordMapper.insertApprovalRecord(inApprovalRecord);
    }

    /**
     * 新增审批记录信息
     * @param sequence 序号
     * @param approvalConfigList 审批记录
     * @param syTransferT 调拨实体类
     * @param loginUser 登录人信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void addApprovalConfig(int sequence, List<ApprovalConfig> approvalConfigList, SyTransferT syTransferT, LoginUser loginUser) {
        String status = Constants.NOT_APPROVED;
        if (sequence == 2) {
            status = Constants.APPROVE;
        }
        for (ApprovalConfig approvalConfig : approvalConfigList) {
            ApprovalRecord approvalRecord = getApprovalRecord(syTransferT, loginUser);
            approvalRecord.setSequence(sequence);
            approvalRecord.setApprovalStatus(status);
            approvalRecord.setApproverId(approvalConfig.getUserId());
            approvalRecord.setApproverName(approvalConfig.getUsername());
            approvalRecordMapper.insertApprovalRecord(approvalRecord);
        }
    }

    /**
     * 获取审批记录对象
     *
     * @param syTransferT 调拨实体类
     * @param loginUser 登录人信息
     * @return
     */
    private ApprovalRecord getApprovalRecord(SyTransferT syTransferT, LoginUser loginUser) {
        ApprovalRecord approvalRecord = new ApprovalRecord();
        approvalRecord.setSerialNum(syTransferT.getSerialNum());
        approvalRecord.setUserId(syTransferT.getResponsibleId());
        approvalRecord.setOrderId(syTransferT.getId());
        approvalRecord.setUserName(syTransferT.getResponsibleName());
        approvalRecord.setUpdateTime(DateUtils.parseDate(DateUtils.getTime()));
        approvalRecord.setUpdateBy(loginUser.getUsername());
        approvalRecord.setCreateBy(loginUser.getUsername());
        approvalRecord.setCreateTime(DateUtils.parseDate(DateUtils.getTime()));
        return approvalRecord;
    }

    /**
     * 新增调拨单
     * @param syTransferT 调拨实体类
     * @param loginUser 登录人信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void addSyTransfer(SyTransferT syTransferT, LoginUser loginUser) {
        //新增调拨单
        syTransferT.setCreateBy(loginUser.getUsername());
        syTransferT.setCreateTime(DateUtils.getNowDate());
        syTransferT.setUpdateBy(loginUser.getUsername());
        syTransferT.setUpdateTime(DateUtils.getNowDate());
        syTransferT.setDataState("1");
        syTransferT.setEquipmentStatus("0");
        syTransferT.setLogisticsStatus("0");
        syTransferTMapper.insertSyTransferT(syTransferT);
        //新增调拨产品
        for (SyTransferProductT bo : syTransferT.getSyTransferProductTList()) {
            //校验调拨数量是否在机器可用数量区间
            Stock stock = stockMapper.selectStockByWarehouseNameAndModelAndProductName(bo.getWarehouseName(), bo.getModel(), bo.getProductName());
            if (Objects.isNull(stock)){
                throw new BaseException("查询库存异常",StringUtils.format("查询库存异常-仓库名称{}，型号{}，产品名称{}",bo.getWarehouseName(), bo.getModel(), bo.getProductName()));
            }
            //获取已提单但还没出库的数据
            Long quantity = syTransferProductTMapper.selectProductQuantity(bo);
            long quantitySum= quantity + bo.getQuantity();
            if (bo.getQuantity()>(stock.getAvailableQuantity() -quantitySum)){
                throw new BaseException("超出可用库存数量",StringUtils.format("超出可用库存数量-仓库名称{}，型号{}，产品名称{}",bo.getWarehouseName(), bo.getModel(), bo.getProductName()));
            }
            bo.setDataState("1");
            bo.setTransferNo(syTransferT.getSerialNum());
            bo.setCreateBy(loginUser.getUsername());
            bo.setCreateTime(DateUtils.getNowDate());
            bo.setUpdateBy(loginUser.getUsername());
            bo.setUpdateTime(DateUtils.getNowDate());
            syTransferProductTMapper.insertSyTransferProductT(bo);
        }
    }

    /**
     * 修改库存调拨
     * 
     * @param syTransferT 库存调拨
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateSyTransferT(SyTransferT syTransferT)
    {
        //修改主表数据
        syTransferTMapper.updateSyTransferT(syTransferT);
        if (!CollectionUtils.isEmpty(syTransferT.getSyTransferProductTList())){
            //修改关联产品
            syTransferProductTMapper.deleteSyTransferProductTByIds(syTransferT.getSyTransferProductTList().stream().map(SyTransferProductT::getId).toArray(Long[]::new));
            for (SyTransferProductT syTransferProductT : syTransferT.getSyTransferProductTList()) {
                syTransferProductT.setId(null);
                syTransferProductTMapper.insertSyTransferProductT(syTransferProductT);
            }
        }
        return AjaxResult.success();
    }

    /**
     * 批量删除库存调拨
     * 
     * @param ids 需要删除的库存调拨主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult deleteSyTransferTByIds(Long[] ids)
    {
        List<SyTransferT> syTransferList = syTransferTMapper.selectSyTransferTByIds(ids);
        if (CollectionUtils.isEmpty(syTransferList)){
            return AjaxResult.error("批量删除库存调拨删除失败，数据为空");
        }
        List<String> collect = syTransferList.stream().map(SyTransferT::getSerialNum).collect(Collectors.toList());
        syTransferTMapper.deleteSyTransferTByIds(ids);
        syTransferProductTMapper.deleteSyTransferProductTByTransferNoList(collect);
        //删除审批记录
        for (SyTransferT syTransferT : syTransferList) {
            approvalRecordMapper.deleteApprovalRecordBySerialNum(syTransferT.getSerialNum());
        }
        return AjaxResult.success();
    }

    /**
     * 删除库存调拨信息
     * 
     * @param id 库存调拨主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult deleteSyTransferTById(Long id)
    {
        SyTransferT syTransferT = syTransferTMapper.selectSyTransferTById(id);
        if (Objects.isNull(syTransferT)){
            return AjaxResult.error("删除失败，记录不存在");
        }
        syTransferTMapper.deleteSyTransferTById(id);
        String serialNum = syTransferT.getSerialNum();
        syTransferProductTMapper.deleteSyTransferProductTByTransferNoList(Collections.singletonList(serialNum));
        approvalRecordMapper.deleteApprovalRecordBySerialNum(serialNum);
        return AjaxResult.success();
    }

    /**
     * 根据物流编号查询
     * @param
     * @return
     */
    @Override
    public List<SyTransferT> getByOrderNo(String orderNo[]){
        return syTransferTMapper.getByOrderNo(orderNo);
    }
}
